// TileScrollView.m
// By Jayson Adams, NeXT Developer Support Team
// Modified for 3.0 by Ali Ozer, May '92
// You may freely copy, distribute and reuse the code in this example.
// NeXT disclaims any warranty of any kind, expressed or implied, as to its
// fitness for any particular use.

#import <appkit/ClipView.h>
#import <appkit/Matrix.h>

#import "RulerView.h"
#import "PostScriptView.h"

#import "TileScrollView.h"


@implementation TileScrollView


/* instance methods */

- initFrame:(const NXRect *)theFrame
{
    NXRect	rulerViewRect = {{0.0, 0.0}, {NX_WIDTH(theFrame), 20.0}};
    
    [super initFrame:theFrame];
    
  /* create a rulerView */
    rulerView = [[RulerView alloc] initFrame:&rulerViewRect];
    
  /* make a clipView to hold it (we'll adjust its size & position in tile) */
    rulerClipView = [[ClipView alloc] initFrame:&rulerViewRect];
    [self addSubview:rulerClipView];
    [rulerClipView setDocView:rulerView];

  /* remember the current scale factor */
    oldScaleFactor = 1.0;
    
    return self;
}

- free
{
    [rulerView free];
    [rulerClipView free];

    return [super free];
}

- changeScale:sender
{
    float scaleFactor = [[sender selectedCell] tag] / 100.0;
    
    if (scaleFactor != oldScaleFactor) {
	[window disableDisplay];
	[[self docView] scale:scaleFactor / oldScaleFactor];
	[rulerView scale:scaleFactor / oldScaleFactor :1.0];
	[self fixUpRuler];
	[window reenableDisplay];
	[self display];
	oldScaleFactor = scaleFactor;
    }
    
    return self;
}

- (void)fixUpRuler
{
    NXRect docViewBounds, rulerViewBounds;
    [window disableDisplay];
    [[self docView] getBounds:&docViewBounds];
    [rulerView getBounds:&rulerViewBounds];
    [rulerView sizeTo:NX_WIDTH(&docViewBounds) :NX_HEIGHT(&rulerViewBounds)];
    [self tile];
    [window reenableDisplay];
    [self display];
}

- setDocView:aView
{
    id retVal = [super setDocView:aView];
    [self fixUpRuler];
    return retVal;
}

- tile
/*
 * tile gets called whenever the scrollView changes size.  Its job is to resize
 * all of the scrollView's "tiled" views (scrollers, contentView and any other
 * views we might want to place in the scrollView's bounds).
 */
{
    NXRect	contentViewRect, rulerRect, rulerClipRect, scrollerRect,
		buttonRect, stubRect;
    
  /* resize and arrange the scrollers and contentView as usual */ 
    [super tile];
    
  /* make sure the popup list and stub view are subviews of us */
    if ([popupListButton superview] != self) {
	[self addSubview:popupListButton];
    }
    if ([stubView superview] != self) {
	[self addSubview:stubView];
    }
    
  /* cut a slice from the contentView to make room for the rulerView */
    [contentView getFrame:&contentViewRect];
    [rulerView getFrame:&rulerRect];
    NXDivideRect(&contentViewRect, &rulerClipRect, NX_HEIGHT(&rulerRect), 1);
    [rulerClipView setFrame:&rulerClipRect];
    [contentView setFrame:&contentViewRect];
    
  /* shrink the vScroller to make room for the stub view */
    [vScroller getFrame:&scrollerRect];
    NXDivideRect(&scrollerRect, &stubRect, NX_HEIGHT(&rulerRect), 1);
    [vScroller setFrame:&scrollerRect];
    [stubView setFrame:&stubRect];
    
  /* now make the hScroller smaller and stick the popupList next to it */
    [hScroller getFrame:&scrollerRect];
    NXDivideRect(&scrollerRect, &buttonRect, 60.0, 2);
    [hScroller setFrame:&scrollerRect];
    NXInsetRect(&buttonRect, 1.0, 1.0);
    [popupListButton setFrame:&buttonRect];
    
    return self;
}

- scrollClip:aClipView to:(NXPoint *)aPoint
{
    NXPoint	colOrigin;
    NXRect	colBounds;
    
  /* don't do anything if it's not the contentView */
    if (aClipView != contentView) {
	return self;
    }
    
  /* turn off drawing (to the screen) */
    [window disableFlushWindow];
    
  /* scroll the contentView to the new origin */
    [aClipView rawScroll:aPoint];
    
  /* compute new origin for the rulerView (don't let it scroll vertically) */
    [rulerClipView getBounds:&colBounds];
    colOrigin.x = aPoint->x;
    colOrigin.y = colBounds.origin.y;
    
  /* scroll the ruler view to that point */
    [rulerClipView rawScroll:&colOrigin];
    
  /* send results to screen */
    [[window reenableFlushWindow] flushWindow];
    
    return self;
}

@end
